package com.plian.system.service.ms.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.plian.Tools.*;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.constant.sys.FormStatusConstant;
import com.plian.system.constant.sys.FormTypeConstant;
import com.plian.system.entity.ms.DailyThing;
import com.plian.system.mapper.ms.DailyThingMapper;
import com.plian.system.mybatis.base.BaseFlowService;
import com.plian.system.mybatis.base.BaseServiceImpl;
import com.plian.system.mybatis.support.Condition;
import com.plian.system.service.ms.IDailyThingService;
import com.plian.system.service.sys.code.IFormCodeService;
import com.plian.system.service.sys.file.FileService;
import com.plian.system.service.wf.FormWorkflowService;
import com.plian.system.vo.ms.DailyThingVO;
import com.plian.system.wrapper.ms.DailyThingWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static com.plian.system.constant.sys.FormStatusConstant.UNREVIEWED;

/**
 * 月度计划表 服务实现类
 *
 * @author xiaohu
 */
@Slf4j
@Service
@AllArgsConstructor
public class DailyThingServiceImpl extends BaseServiceImpl<DailyThingMapper, DailyThing> implements IDailyThingService, BaseFlowService {

	private FormWorkflowService formWorkflowService;

	private IFormCodeService formCodeService;

	private FileService fileService;

	private DailyThingWrapper dailyThingWrapper;

	@Override
	public HashMap<String,Object> commit(String id) {
		handleStatus(Long.valueOf(id), FormStatusConstant.FLOW);
		//将需要提交的流程变量返回，用于工作流侧
		return new HashMap<String,Object>();
	}

	@Override
	public Boolean finish(String id) {
		return handleStatus(Long.valueOf(id), FormStatusConstant.FINISH);
	}

	@Override
	public Boolean reject(String id, int formState, String comment) {
		return handleStatus(Long.valueOf(id), formState);
	}

	@Override
	public Boolean checkIsExisted(Long id, String code) {
		if (Optional.ofNullable(code).isPresent()) {
			DailyThing dailyThing = new DailyThing();
			dailyThing.setCode(code);
			if (Optional.ofNullable(getOne(Condition.getQueryWrapper(dailyThing))).isPresent()) {
				if (id == null || !id.equals(getOne(Condition.getQueryWrapper(dailyThing)).getId())) {
					return false;
				}
			}
		}
		return true;
	}

	@Override
	@Transactional(rollbackFor=RuntimeException.class)
	public Boolean submit(DailyThing dailyThing) {
		if (!Optional.ofNullable(dailyThing.getStatus()).isPresent()){
			dailyThing.setStatus(FormStatusConstant.UNREVIEWED);
		}
		boolean result = saveOrUpdate(dailyThing);
		HashMap<String, Object> processVariable = new HashMap<>();
		formWorkflowService.startProcessAndSimulate(String.valueOf(dailyThing.getId()),dailyThing.getFormType(),processVariable);
		return result;
	}

	@Override
	public Boolean checkCancel(Long id) {
		DailyThing dailyThing = getById(id);
		if (!Optional.ofNullable(dailyThing).isPresent()) {
			return false;
		}
		return true;
	}

	@Override
	public boolean saveOrUpdate(DailyThing dailyThing) {
		if (!Optional.ofNullable(dailyThing.getStatus()).isPresent()) {
			dailyThing.setStatus(UNREVIEWED);
		}
		boolean flag = false;
		if (!Optional.ofNullable(dailyThing.getId()).isPresent()) {
			//根据单据类型生成单据编码
			dailyThing.setCode(formCodeService.getCode(FormTypeConstant.MS_DAILY_THING));
			dailyThing.setFormType(String.valueOf(FormTypeConstant.MS_DAILY_THING));
			flag = true;
		}
		boolean result = super.saveOrUpdate(dailyThing);
		if (flag){
			fileService.saveAll(String.valueOf(dailyThing.getId()), dailyThing.getDocList());
		}else {
			fileService.edit(String.valueOf(dailyThing.getId()), dailyThing.getDocList());
		}
		return result;
	}


	/**
	 * 统一处理状态机事件方法
	 *
	 * @param id          主键
	 * @param updateStatus 更新状态
	 * @return boolean
	 */
	private Boolean handleStatus(Long id, int updateStatus) {
		try {
			DailyThing dailyThing = getById(id);
			/**
			 * 设置审批人和审批时间
			 */
			if (updateStatus == FormStatusConstant.FINISH){
				dailyThing.setApprovedUser(TokenUtil.getTokenUserId());
				Date now = DateUtil.now();
				dailyThing.setApprovedTime(now);
			}
			dailyThing.setStatus(updateStatus);
			updateById(dailyThing);
			return true;
		} catch (Exception e) {
			log.error(ExceptionUtils.getFullStackTrace(e));
			return false;
		}
	}

	@Override
	public List<PageData> findByIds(List<String> formIds) {
		LambdaQueryWrapper<DailyThing> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.in(DailyThing::getId, Func.toLongList(org.apache.commons.lang3.StringUtils.join(formIds, StringPool.COMMA)));
		List<DailyThing> dailyThings = list(queryWrapper);
		List<DailyThingVO> dailyThingVOS = dailyThingWrapper.entityToVO(dailyThings);
		List<PageData> pageDataList = new ArrayList<>();
		try{
			if (CollectionUtil.isNotEmpty(dailyThingVOS)){
				for (DailyThingVO vo : dailyThingVOS){
					PageData pd = new PageData();
					pd.put("id", vo.getId());
					pd.put("UNITNAME", vo.getFillCompanyName());
					pd.put("APPLICANTNAME", vo.getCreateUserName());
					pd.put("applicantId", vo.getCreateUser());
					pd.put("applyOrganizationId", vo.getFillCompanyName());
					pd.put("formType", FormTypeConstant.MS_DAILY_THING);
					pd.put("orgName", vo.getFillCompanyName());
					pageDataList.add(pd);
				}
			}
			return pageDataList;
		} catch (Exception e) {
			log.error(ExceptionUtils.getFullStackTrace(e));
		}
		return pageDataList;
	}

	@Override
	public List<Integer> getFormType() {
		return Arrays.asList(FormTypeConstant.MS_DAILY_THING);
	}

	@Override
	public void goBackToStash(String formId) {
		handleStatus(Long.valueOf(formId), UNREVIEWED);
	}





}
